package com.mima.minaserver.server;

import java.text.SimpleDateFormat;
import java.util.Date;

import org.apache.mina.core.session.IoSession;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.mima.minaserver.entity.Camera;
import com.mima.minaserver.entity.HeartBeatEntity;
import com.mima.minaserver.entity.MyUUID;
import com.mima.minaserver.entity.OnOffLogEntity;
import com.mima.minaserver.repository.OnOffLogRepository;
import com.mima.minaserver.service.IotServerMessage;
import com.mima.minaserver.service.MessageSender;
import com.mima.minaserver.utils.ParameterUtils;

import net.sf.ehcache.Cache;
import net.sf.ehcache.CacheManager;
import net.sf.ehcache.Element;

public class IOTServerHandlerThread implements Runnable {
	
	private static Logger logger = LoggerFactory.getLogger(IOTServerHandlerThread.class);
	private IoSession session;
	private Object message;
	private IotServerMessage iotServerMessage;
	private  CacheManager cacheManager;
	private MessageSender messageSender;
	private ParameterUtils parameterUtils;
	private OnOffLogRepository onOffLogRepository;
	
	public IOTServerHandlerThread(IotServerMessage iotServerMessage,IoSession session,Object message,CacheManager cacheManager,MessageSender messageSender,ParameterUtils parameterUtils,OnOffLogRepository onOffLogRepository) {
		this.session = session;
		this.message = message;
		this.iotServerMessage = iotServerMessage;
		this.cacheManager = cacheManager;
		this.messageSender = messageSender;
		this.parameterUtils = parameterUtils;
		this.onOffLogRepository=onOffLogRepository;
	}
	@Override
	public void run() {
		try {
			byte[] buffer = (byte[]) message;
			byte[] heard = new byte[6];
			System.arraycopy(buffer, 0, heard, 0, 6);
			String headpString = new String(heard);
			
			if ("HEARTP".equals(headpString.toUpperCase())) {
				byte[] uuid = new byte[32];
				byte[] dateTime = new byte[8];
				byte[] opened = new byte[1];
				byte[] key_id = new byte[1];
				byte[] uNameAndPasswd = new byte[buffer.length - heard.length - uuid.length - dateTime.length -opened.length - key_id.length];
	
				System.arraycopy(buffer, heard.length, uuid, 0, uuid.length);
				String uuidString = new String(uuid);
	
				System.arraycopy(buffer, heard.length+uuid.length, dateTime, 0, dateTime.length);
				Date heartTime = IOTServerHandler.BytesToDate(dateTime);
				
				System.arraycopy(buffer, heard.length+uuid.length+dateTime.length, opened, 0, opened.length);
				Integer openedInt = IOTServerHandler.bytesToInt(opened, 0); //0表示都关闭，1表示标清开，2表示高清开，3表示都开
				
				System.arraycopy(buffer, heard.length+uuid.length+dateTime.length+opened.length, key_id, 0, key_id.length);
				Integer keyId = IOTServerHandler.bytesToInt(key_id, 0);

				System.arraycopy(buffer, heard.length+uuid.length+dateTime.length+opened.length+key_id.length, uNameAndPasswd, 0, uNameAndPasswd.length);
				String uNameAndPwd = new String(uNameAndPasswd);
				String user = uNameAndPwd.split("\\,")[0];
				String pwd = uNameAndPwd.split("\\,")[1];
				logger.info("{HEARDP=" + headpString + ",UUID=" + uuidString + ",DATE=" + heartTime+",opened="+openedInt + ",Key_id=" + keyId + ",USER_PWD="
						+ uNameAndPwd + "}");
				MyUUID uuidObject = iotServerMessage.findUUIDByUUID(uuidString);
	
				if (uuidObject == null) {
					logger.info("UUID:" + uuidString + " NOT FOUND!");
					return;
				} else {
					
					Camera camera = iotServerMessage.findDeviceByUUID(uuidString);
					if (!user.trim().equals(uuidObject.getAccount())) {
						iotServerMessage.sendUnameAndPWDMessage(session, uuidObject.getAccount(), uuidObject.getPassword());
						iotServerMessage.PushLoginInfo(uuidObject.getUuid(),uuidObject.getKey_id(),uuidObject.getSecret_key(), parameterUtils.getUrl_ali());
						messageSender.sendFaultMessage(uuidObject.getUuid(), 1);
					}else if(!pwd.trim().equals(uuidObject.getPassword())) {
						iotServerMessage.sendUnameAndPWDMessage(session, uuidObject.getAccount(), uuidObject.getPassword());
						iotServerMessage.PushLoginInfo(uuidObject.getUuid(),uuidObject.getKey_id(),uuidObject.getSecret_key(), parameterUtils.getUrl_ali());
						messageSender.sendFaultMessage(uuidObject.getUuid(), 2);
					}else if(!keyId.equals(uuidObject.getKey_id())) {
						iotServerMessage.sendSecretKeyMessage(session,uuidObject.getUuid(),uuidObject.getKey_id(),uuidObject.getSecret_key());
						iotServerMessage.PushLoginInfo(uuidObject.getUuid(),uuidObject.getKey_id(),uuidObject.getSecret_key(), parameterUtils.getUrl_ali());
						messageSender.sendFaultMessage(uuidObject.getUuid(), 3);
						
					}else if(openedInt.intValue() != camera.getOpened().intValue()) {
						//0表示都关闭，1表示标清开，2表示高清开，3表示都开
						if(0 == camera.getOpened().intValue()) {
							iotServerMessage.sendDeviceOnOFFMessage(session,0,Integer.valueOf(parameterUtils.getAli_streaming_channal_gaoqing()));
							iotServerMessage.sendDeviceOnOFFMessage(session,0,Integer.valueOf(parameterUtils.getAli_streaming_channal_biaoqing()));
						}else if(1 == camera.getOpened().intValue()) {
							iotServerMessage.sendDeviceOnOFFMessage(session,0,Integer.valueOf(parameterUtils.getAli_streaming_channal_gaoqing()));
						}else if(2 == camera.getOpened().intValue()) {
							iotServerMessage.sendDeviceOnOFFMessage(session,0,Integer.valueOf(parameterUtils.getAli_streaming_channal_biaoqing()));
						}else if(3 == camera.getOpened().intValue()) {
							iotServerMessage.sendDeviceOnOFFMessage(session,1,Integer.valueOf(parameterUtils.getAli_streaming_channal_gaoqing()));
							iotServerMessage.sendDeviceOnOFFMessage(session,1,Integer.valueOf(parameterUtils.getAli_streaming_channal_biaoqing()));
						}
					}else if(camera.getStatus() == 0) {
						iotServerMessage.updateStatusByUUID(1, uuidString);
						OnOffLogEntity onOffLogEntity = new OnOffLogEntity(uuidString, 1, new Date());
						onOffLogRepository.save(onOffLogEntity);
						//iotServerMessage.sendDeviceOnOFFMessage(session, camera.getStatus());
						String message = "{\"uuid\":\""+uuidString+"\",\"status\":"+1+",\"time\":\""+ new Date() +"\"}";
						messageSender.sendOnOffAlarmMessage(message);
						messageSender.sendFaultMessage(uuidObject.getUuid(), 0);
						
					}else {
						HeartBeatEntity heartBeatEntity = iotServerMessage.fetchHeadBeat(uuidString);
						Date currentHeartTime = new Date();
						if(heartBeatEntity == null) iotServerMessage.insertHeadBeat(uuidString, user, pwd, currentHeartTime,keyId);
						else {
							if(currentHeartTime.getTime() > heartBeatEntity.getHeartpTime().getTime()) iotServerMessage.updateHeadBeat(uuidString, user, pwd,currentHeartTime,keyId);
						}
						iotServerMessage.insertHeadBeatToMongo(uuidString, user, pwd,currentHeartTime,keyId);
						messageSender.sendFaultMessage(uuidString, 0);
					}
					
					freshSessionCache(uuidString,session);
				}
			}

			if ("RTPURL".equals(headpString.toUpperCase())) {
				byte[] uuid = new byte[32];
				byte[] rtspurl = new byte[buffer.length - heard.length - uuid.length];
	
				System.arraycopy(buffer, 6, uuid, 0, uuid.length);
				String uuidString = new String(uuid);

	
				System.arraycopy(buffer, 38, rtspurl, 0, rtspurl.length);
				String rtspurlString = new String(rtspurl);
				logger.info("{HEARDP=" + headpString + ",UUID=" + uuidString + ",RTP_URL="
						+ rtspurlString + "}");
				MyUUID MUUID = iotServerMessage.findUUIDByUUID(uuidString);
				if (MUUID == null) {
					logger.info("UUID:" + uuidString + " NOT FOUND!");
					return;
				} else {
					//通知中心平台
					String time = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
					String ipChangeMessage = "{\"uuid\":\""+uuidString+"\",\"ip\":\""+rtspurlString+"\",\"time\":\""+time+"\"}";	  
					messageSender.sendIpChangeMessage(ipChangeMessage);
					iotServerMessage.updateCameraRtmpurl(rtspurlString.trim(), MUUID.getUuid());
				}
				
				freshSessionCache(uuidString,session);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	

	public void freshSessionCache(String uuid,IoSession session) {
		Cache cache = cacheManager.getCache("IotServerCache");
		System.out.println(cache.getSize());
		Element element = cache.get(uuid);
		if(element == null) {
			element = new Element(uuid, session);
			cache.put(element);
		}else {
			IoSession cacheSession = (IoSession)element.getObjectValue();
			if(cacheSession != session) {
				cache.remove(uuid);
				element = new Element(uuid, session);
				cache.put(element);
			}
		}
	
	}
}
